<template>
    <view class="container">
        <view style="font-weight: bold;font-size: 36rpx;">PHPSocket.IO，PHP跨平台实时通讯框架</view>
        <view style="font-weight: bold;font-size: 36rpx;color: red;">仅H5版能用，微信小程序不能连接上服务</view>
        <view>
            PHPSocket.IO是PHP版本的Socket.IO服务端实现，基于workerman开发，用于替换node.js版本Socket.IO服务端。PHPSocket.IO底层采用websocket协议通讯，如果客户端不支持websocket协议， 则会自动采用http长轮询的方式通讯。PHPSocket.IO实现的Polling通信机制包括Adobe Flash Socket、AJAX长轮询、JSONP轮询等。具体采用哪种机制通讯对于开发者完全透明， 开发者使用的是统一的接口。

            PHPSocket.IO设计的目标是利用PHP构建能够在不同浏览器和移动设备上良好运行的实时应用，如实时分析系统、在线聊天室、在线客服系统、评论系统、WebIM等。 PHPSocket.IO与workerman的区别是，PHPSocket.IO基于workerman开发，workerman有的特性PHPSocket.IO都支持。 PHPSocket.IO最大的优势是对各种浏览器的兼容性更好。
        </view>

        <view style="margin-top: 30rpx;background-color: #fff;">
            <view v-for="(item, index) in messageList" :key="index">
                <view>
                    <text style="line-height: 50rpx;">{{ item.content }} {{ formatTime(item.create_time, 'HH:mm') }}</text>
                    <text>{{ item.is_read == 1 ? '已读' : '未读'}}</text>
                </view>
            </view>
        </view>

        <view class="action-wrap">
            <view class="action-box">
                <view class="input-panel">
                    <uni-easyinput
                        v-model="params.content"
                        focus
                        primaryColor="#27BA9B"
                        placeholder="问医生">
                    </uni-easyinput>
                </view>
                <!-- 上传图片 -->
                <view class="picker-panel">
                    <uni-file-picker
                        limit="1" 
                        :del-icon="false" 
                        disable-preview 
                        :imageStyles="imageStyles"
                        file-mediatype="image"
                        @select="hanleUploadImage"
                    >
                        <text class="iconfont icon-tupian"></text>
                    </uni-file-picker>
                </view>
                <button class="btn-panel" @click="handleSendMessage">发送</button>
            </view>
        </view>
    </view>
</template>

<script lang="ts" setup>
import { useUserStore } from "@/stores";
import type { Message, SendMessageParams } from "@/types/inquiryRoom";
import { onLoad } from "@dcloudio/uni-app"
// npm install socket.io-client@2.3.0
// npm install socket.io-client@2.5.0
import io from 'socket.io-client'
import { nextTick, onUnmounted, reactive, ref } from "vue"
import {formatTime} from '@/utils/tools'

// 用户存储
const userStore = useUserStore()
// 参数地址：https://socket.io/zh-CN/docs/v2/client-initialization/
const option = reactive({
    transports: [
        // 指定传输方式，如WebSocket
        'websocket',
        // 'polling'
    ],

    // 是否自动连接
    autoConnect: true,

    // 是否自动重新连接
    reconnection: true,

    // 重新连接尝试次数
    reconnectionAttempts: 3,

    // 重新连接延迟时间（毫秒）
    reconnectionDelay: 1000,

    // 指定token,高版本用法
    // auth: {
    //     token: `Bearer ${userStore.profile?.token}`
    // },

    // 自定义查询参数
    query: {
        token: userStore.profile?.token,
        oid: 10000
    },
    // 其他可选参数...
    // path: '/socket.io',
})

// H5版
const url = ref('http://127.0.0.1:3120')
// const url = 'wss://127.0.0.1:3120';
// const url = 'http://127.0.0.1:3120';

let socket:any

const messageList = reactive<Message[]>([])

onLoad(() => {
    socket = io(url.value, option);
    

    // 监听连接
    socket.on('connect', function() {
        console.log('监听连接');
        // 设置sid
        userStore.setSocketId(socket.id)
        // receiveSaveSid
        // 保存客户端uid与sid映射关系
        socket.emit('saveSid', {uid: userStore.profile ? userStore.profile?.user.uid : 0})
        console.log(socket);
    })

    // 接收保存客户端uid与sid映射关系消息
    socket.on('receiveSaveSid', function({data}: {data: any}) {
        console.log('receiveSaveSid =', data);
    })

    // 接收服务器默认消息
    socket.on('receiveDefultMessageList', function({data}: {data: Message[]}) {
        console.log('receiveDefultMessageList =', data);
        messageList.unshift(...data)

        nextTick(() => {
            window.scrollTo(0, document.body.scrollHeight)
        })
    })

    // 接收服务器消息
    socket.on('receiveChatMessage', async ({data}: {data: any}) => {
        console.log('receiveChatMessage =', data);
        messageList.push(data)

        // 将消息修改为已读
        socket.emit('readChatMessage', {id: data.id})

        // 始终显示新一条消息
        await nextTick()
        window.scrollTo(0, document.body.scrollHeight)
    })

    // 接收http worker消息
    socket.on('receiveDemoHttpWorker', function(data: {data: any}) {
        console.log('receiveDemoHttpWorker data =', data);
        console.log('接收http worker消息');
    })

    // 监听关闭
    socket.on('disconnect', function() {
        console.log('监听关闭');
    })

    // 监听错误
    socket.on('error', function() {
        console.log('监听错误');
    })
})

onUnmounted(() => {
    console.log('onUnmounted');
    
    socket.close()
})


// 发送消息参数
const params = reactive<SendMessageParams>({
    from_uid: userStore.profile ? userStore.profile?.user.uid : 0,
    type:1,
    to_uid: 0,
    content: '',
    image_url: '',
})

// ----------------- 上传图片功能开始 -----------------
// 上传图片样式
const imageStyles = ref(
	{
		width: 50,
		height: 50,
        border:{ // 如果为 Boolean 值，可以控制边框显示与否
            color:"#27BA9B",		// 边框颜色
            width:"1px",		// 边框宽度
            style:"solid", 	// 边框样式
            radius:"50%" 		// 边框圆角，支持百分比
        }
	}
)

// 处理上传图片
const hanleUploadImage = (e: any) => {
    console.log(e);
    
	// imageSrc.value = e.tempFilePaths[0]
}
// ----------------- 上传图片功能结束 -----------------



// ----------------- 发送消息功能开始 -----------------
const handleSendMessage = () => {
    params.from_uid = userStore.profile ? userStore.profile.user.uid : 0
    params.to_uid = params.from_uid == 2185 ? 2173 : 2185
    socket.emit('sendChatMessage', params)
    params.content = ''
}
// ----------------- 发送消息功能结束 -----------------


</script>

<style scoped lang="scss">
.container {
    padding: 20rpx;
    padding-bottom: 120rpx;
    // 操作区域开始
    .action-wrap {
        position: fixed;
        left: 0;
        bottom: 0;
        width: 100%;
        height: 120rpx;
        background-color: #fff;
        z-index: 100;
        .action-box {
            width: 100%;
            height: 120rpx;
            display: flex;
            align-items: center;
            padding: 0 30rpx;
            .input-panel {
                flex: 1;
                padding-right: 10rpx;
            }
            .picker-panel {
                padding-right: 10rpx;
                .iconfont {
                    font-size: 60rpx;
                    color: #27BA9B;
                }
            }

            .btn-panel {
                line-height: 70rpx;
                height: 70rpx;
                width: 120rpx;
            }
        }
    }
    // 操作区域结束
}
</style>